#ifndef PARSER_H
#define PARSER_H

#include <wx/arrstr.h>
#include <wx/event.h>
#include <wx/file.h>
#include <wx/filefn.h>
#include <wx/imaglist.h>
#include <wx/string.h>
#include <wx/thread.h>
#include <wx/timer.h>
#include <wx/treectrl.h>
#include <M_Code_threadpool.h>
#include <sdk_events.h>
#include "parserthread.h"
#include "parser_base.h"

#define PARSER_IMG_NONE                        -2
#define PARSER_IMG_CLASS_FOLDER                 0
#define PARSER_IMG_CLASS                        1
#define PARSER_IMG_CLASS_PRIVATE                2
#define PARSER_IMG_CLASS_PROTECTED              3
#define PARSER_IMG_CLASS_PUBLIC                 4
#define PARSER_IMG_CTOR_PRIVATE                 5
#define PARSER_IMG_CTOR_PROTECTED               6
#define PARSER_IMG_CTOR_PUBLIC                  7
#define PARSER_IMG_DTOR_PRIVATE                 8
#define PARSER_IMG_DTOR_PROTECTED               9
#define PARSER_IMG_DTOR_PUBLIC                  10
#define PARSER_IMG_FUNC_PRIVATE                 11
#define PARSER_IMG_FUNC_PROTECTED               12
#define PARSER_IMG_FUNC_PUBLIC                  13
#define PARSER_IMG_VAR_PRIVATE                  14
#define PARSER_IMG_VAR_PROTECTED                15
#define PARSER_IMG_VAR_PUBLIC                   16
#define PARSER_IMG_MACRO_DEF                    17
#define PARSER_IMG_ENUM                         18
#define PARSER_IMG_ENUM_PRIVATE                 19
#define PARSER_IMG_ENUM_PROTECTED               20
#define PARSER_IMG_ENUM_PUBLIC                  21
#define PARSER_IMG_ENUMERATOR                   22
#define PARSER_IMG_NAMESPACE                    23
#define PARSER_IMG_TYPEDEF                      24
#define PARSER_IMG_TYPEDEF_PRIVATE              25
#define PARSER_IMG_TYPEDEF_PROTECTED            26
#define PARSER_IMG_TYPEDEF_PUBLIC               27
#define PARSER_IMG_SYMBOLS_FOLDER               28
#define PARSER_IMG_VARS_FOLDER                  29
#define PARSER_IMG_FUNCS_FOLDER                 30
#define PARSER_IMG_ENUMS_FOLDER                 31
#define PARSER_IMG_MACRO_DEF_FOLDER             32
#define PARSER_IMG_OTHERS_FOLDER                33
#define PARSER_IMG_TYPEDEF_FOLDER               34
#define PARSER_IMG_MACRO_USE                    35
#define PARSER_IMG_MACRO_USE_PRIVATE            36
#define PARSER_IMG_MACRO_USE_PROTECTED          37
#define PARSER_IMG_MACRO_USE_PUBLIC             38
#define PARSER_IMG_MACRO_USE_FOLDER             39
#define PARSER_IMG_MIN PARSER_IMG_CLASS_FOLDER
#define PARSER_IMG_MAX PARSER_IMG_MACRO_USE_FOLDER


class ClassTreeData : public wxTreeItemData {
  public:
    ClassTreeData( Token* token ) { m_Token = token; }
    Token* GetToken() { return m_Token;  }
    void SetToken( Token* token ) { m_Token = token; }
  private:
    Token* m_Token;
};

class ClassBrowser;

namespace ParserCommon {
  extern int idParserStart;
  extern int idParserEnd;
  enum ParserState {
    ptCreateParser = 1,
    ptReparseFile = 2,
    ptAddFileToParser = 3,
    ptUndefined = 4
  };
}


class Parser : public ParserBase {
    friend class ParserThreadedTask;
  public:
    Parser( wxEvtHandler* parent, M_Code_Project* project );
    virtual ~Parser();
    virtual void AddBatchParse( const StringList& filenames );
    virtual void AddParse( const wxString& filename );
    virtual void AddPredefinedMacros( const wxString& defs );
    virtual void ClearPredefinedMacros();
    virtual const wxString GetPredefinedMacros() const;
    virtual bool UpdateParsingProject( M_Code_Project* project );
    virtual bool ParseBuffer( const wxString& buffer, bool isLocal, bool bufferSkipBlocks = false,
                              bool isTemp = false, const wxString& filename = wxEmptyString,
                              int parentIdx = -1, int initLine = 0 );
    virtual bool ParseBufferForFunctions( const wxString& buffer );
    virtual bool ParseBufferForNamespaces( const wxString& buffer, NameSpaceVec& result );
    virtual bool ParseBufferForUsingNamespace( const wxString& buffer, wxArrayString& result, bool bufferSkipBlocks = true );
    virtual bool Reparse( const wxString& filename, bool isLocal = true );
    virtual bool AddFile( const wxString& filename, M_Code_Project* project, bool isLocal = true );
    virtual bool RemoveFile( const wxString& filename );
    virtual bool IsFileParsed( const wxString& filename );
    virtual bool     Done();
    virtual wxString NotDoneReason();
  protected:
    void StartStopWatch();
    void EndStopWatch();
    unsigned int GetMaxThreads() const { return m_Pool.GetConcurrentThreads(); }
    void SetMaxThreads( unsigned int max ) { m_Pool.SetConcurrentThreads( max ); }
    bool Parse( const wxString& filename, bool isLocal = true, bool locked = false );
    void ReparseModifiedFiles();
    void TerminateAllThreads();
    void OnAllThreadsDone( CodeBlocksEvent& event );
    void OnReparseTimer( wxTimerEvent& event );
    void OnBatchTimer( wxTimerEvent& event );
    void ProcessParserEvent(ParserCommon::ParserState state, int id, const wxString& info = wxEmptyString);
    virtual void ReadOptions();
    virtual void WriteOptions();
  private:
    virtual bool ParseFile( const wxString& filename, bool isGlobal, bool locked = false );
    void ConnectEvents();
    void DisconnectEvents();
    wxEvtHandler* m_Parent;
    M_Code_Project* m_Project;
  protected:
    bool m_UsingCache;
    M_Code_ThreadPool m_Pool;
    bool m_IsParsing;
    bool m_NeedsReparse;
    bool m_IsFirstBatch;
  private:
    wxTimer m_ReparseTimer;
    wxTimer m_BatchTimer;
    wxStopWatch m_StopWatch;
    bool m_StopWatchRunning;
    bool m_IgnoreThreadEvents;
    StringList m_BatchParseFiles;
    wxString m_PredefinedMacros;
    wxString m_LastPredefinedMacros;
    bool m_IsBatchParseDone;
    ParserCommon::ParserState m_ParserState;
    bool m_NeedMarkFileAsLocal;
    typedef std::list<cbThreadedTask*> TasksQueue;
    TasksQueue m_tasksQueue;
    void AddParserThread( cbThreadedTask* task );
    void RemoveParserThread( cbThreadedTask* task );
    void AbortParserThreads();
};

#endif
